/*
 * @Description: 
 * @Author: zhanyinjia
 * @Date: 2022-11-15 17:25:53
 * @LastEditors: zhanyinjia
 * @LastEditTime: 2022-12-12 15:10:36
 */
import FileSaver from 'file-saver'
import XLSXStyle from 'xlsx-style'
import * as XLSX from 'xlsx';
import { merges, values } from './json2'
import { flatExcelHead, flatExcelKeys, flatJson } from './json1'

const createArrayWs = () => {
  let list = []
  for (let i = 0; i < 300; i++) {
    list = list.concat(flatJson)
  }

  //将表头放到原始数据里面去，要保证表头在数组的最前面
  const newData = [flatExcelHead, ...list]
  const ws = XLSX.utils.json_to_sheet(newData, { header: flatExcelKeys, skipHeader: true })
  ws['!cols'] = [
    { wpx: 120 },
    { wpx: 140 },
    { wpx: 100 },
    { wpx: 120 },
    { wpx: 100 },
    { wpx: 80 },
    { wpx: 120 },
    { wpx: 120 },
    { wpx: 60 },
    { wpx: 120 },
    { wpx: 120 },
  ];

  return { sheetName: '物料明细', sheet: ws }
}

const createSpecialWs = () => {
  const ws = XLSX.utils.aoa_to_sheet(
    []
  );

  ws['!cols'] = [
    { wpx: 80 },
    { wpx: 80 },
    { wpx: 80 },
    { wpx: 80 },
    { wpx: 120 },
    { wpx: 120 },
    { wpx: 120 },
    { wpx: 200 }
  ];

  ws['!ref'] = 'A1:H24';

  ws['!merges'] = merges.reduce((prev, next) => {
    prev.push({
      s: XLSX.utils.decode_cell(next.s),
      e: XLSX.utils.decode_cell(next.e),
    })
    return prev
  }, [])

  const range = XLSX.utils.decode_range(ws['!ref']);

  for (let R = range.s.r; R <= range.e.r; ++R) {
    for (let C = range.s.c; C <= range.e.c; ++C) {
      const cell_address = { c: C, r: R };
      /* if an A1-style address is needed, encode the address */
      const cell_ref = XLSX.utils.encode_cell(cell_address);

      const obj = values[cell_ref] || { v: '' }
      const config = {
        t: 's',
        v: obj.v
      }

      if (R >= 6 && C >= 0 && (R <= 19 && C <= 7)) {
        config.s = new CellStyle()
      } else {
        const styleSet = { borderColor: 'FFFFFF' }

        if (obj.style) {
          Object.assign(styleSet, obj.style)
        }
        config.s = new CellStyle(styleSet)
      }

      ws[cell_ref] = config
    }
  }

  return { sheetName: '发票封面', sheet: ws }
}

class CellStyle {
  constructor({ borderColor = '000000', ftSize = 12, ftBold = false } = {}) {
    this.alignment = {
      horizontal: 'center',
      vertical: 'center',
      wrapText: true
    }

    this.border = ['top', 'bottom', 'left', 'right'].reduce((prev, next) => {
      prev[next] = {
        style: 'thin',
        color: { rgb: borderColor }
      }
      return prev
    }, {})

    this.font = {
      name: '宋体',
      sz: ftSize,
      bold: ftBold
    }
  }
}

/**
 * @description: 保存多个worksheet成workbook并导出excel
 * @param {*} sheetList   [{sheetName:'',sheet:worksheet}...]
 * @param {*} fileName    要保存的文件名（带文件后缀）
 * @return {*}
 * @author: zhanyinjia
 */
const saveSheet = (sheetList, fileName = 'excel.xlsx') => {
  const workbook = sheetList.reduce((prev, next) => {
    prev.SheetNames.push(next.sheetName)
    prev.Sheets[next.sheetName] = next.sheet
    return prev
  }, {
    SheetNames: [],
    Sheets: {}
  })
  // 生成excel的配置项
  const wopts = {
    bookType: 'xlsx', // 要生成的文件类型
    bookSST: false, // 是否生成Shared String Table，官方解释是，如果开启生成速度会下降，但在低版本IOS设备上有更好的兼容性
    type: 'binary'
    // showGridLines: false
  };
  // 这里要调用XLSXStyle.write，因为设置了单元格样式，如果用XLSX.write则单元格样式设置无效
  const wbout = XLSXStyle.write(workbook, wopts);
  const blob = new Blob([s2ab(wbout)], { type: "application/octet-stream" });
  FileSaver.saveAs(blob, fileName)
}

// 字符串转ArrayBuffer
const s2ab = (s) => {
  var buf = new ArrayBuffer(s.length);
  var view = new Uint8Array(buf);
  for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
  return buf;
}

export { createArrayWs, createSpecialWs, saveSheet }
